const { DataTypes } = require('sequelize');
const sequelize = require('../config/database');
const User = require('./User');
const Video = require('./Video');

// 收藏模型定义
const Favorate = sequelize.define('Favorate', {
  // 用户ID
  user_id: {
    type: DataTypes.BIGINT,
    allowNull: false,
    primaryKey: true,
    references: {
      model: 'users',
      key: 'id'
    },
    onDelete: 'CASCADE'
  },
  
  // 视频ID
  video_id: {
    type: DataTypes.BIGINT,
    allowNull: false,
    primaryKey: true,
    references: {
      model: 'videos',
      key: 'id'
    },
    onDelete: 'CASCADE'
  },
  
  // 创建时间
  createdAt: {
    type: DataTypes.DATE,
    allowNull: false,
    defaultValue: DataTypes.NOW
  },
  
  // 更新时间
  updatedAt: {
    type: DataTypes.DATE,
    allowNull: false,
    defaultValue: DataTypes.NOW
  }
}, {
  // 表配置
  tableName: 'favorate',
  timestamps: true,
  underscored: true, // 使用下划线命名
  charset: 'utf8mb4',
  collate: 'utf8mb4_unicode_ci',
  indexes: [
    {
      fields: ['user_id']
    },
    {
      fields: ['video_id']
    }
  ]
});

// 关联关系
Favorate.belongsTo(User, { foreignKey: 'user_id', as: 'user' });
Favorate.belongsTo(Video, { foreignKey: 'video_id', as: 'video' });

// 创建收藏前的钩子：检查是否已经收藏
Favorate.beforeCreate(async (favorate, options) => {
  const existingFavorate = await Favorate.findOne({
    where: {
      user_id: favorate.user_id,
        video_id: favorate.video_id
    }
  });
  
  if (existingFavorate) {
    throw new Error('用户已经收藏过该视频');
  }
});

// 创建收藏后的钩子：更新视频收藏数
Favorate.afterCreate(async (favorate) => {
  const video = await Video.findByPk(favorate.video_id);
  if (video) {
    await video.incrementFavoriteCount();
  }
});

// 删除收藏后的钩子：更新视频收藏数
Favorate.afterDestroy(async (favorate) => {
  const video = await Video.findByPk(favorate.video_id);
  if (video) {
    await video.decrementFavoriteCount();
  }
});

// 类方法：检查用户是否收藏了视频
Favorate.isUserFavoritedVideo = async function(userId, videoId) {
  const favorite = await this.findOne({
    where: {
      user_id: userId,
      video_id: videoId
    }
  });
  return favorite !== null;
};

// 类方法：检查用户是否收藏了视频 (控制器使用的方法名)
Favorate.isFavorited = async function(userId, videoId) {
  return await this.isUserFavoritedVideo(userId, videoId);
};

// 类方法：收藏视频
Favorate.favoriteVideo = async function(userId, videoId) {
  try {
    const favorite = await this.create({
      user_id: userId,
      video_id: videoId
    });
    return { favorited: true, favorite };
  } catch (error) {
    return { favorited: false, error: error.message };
  }
};

// 类方法：取消收藏
Favorate.unfavoriteVideo = async function(userId, videoId) {
  const deleted = await this.destroy({
    where: {
      user_id: userId,
      video_id: videoId
    }
  });
  return { unfavorited: deleted > 0 };
};

// 类方法：获取用户收藏的视频列表
Favorate.getUserFavoriteVideos = async function(userId, limit = 20, offset = 0) {
  return await Video.findAll({
    include: [
      {
        model: Favorate,
        as: 'favorites',
        where: {
          user_id: userId
        }
      },
      {
        model: User,
        as: 'user',
        attributes: ['id', 'username', 'avatar']
      }
    ],
    where: {
      status: 1 // 只返回审核通过的视频
    },
    order: [['favorites', 'created_at', 'DESC']],
    limit,
    offset
  });
};

// 类方法：获取视频的收藏用户列表
Favorate.getVideoFavorites = async function(videoId, limit = 20, offset = 0) {
  return await User.findAll({
    include: [
      {
        model: Favorate,
        as: 'favorites',
        where: {
          video_id: videoId
        }
      }
    ],
    order: [['favorites', 'created_at', 'DESC']],
    limit,
    offset
  });
};

// 类方法：切换收藏状态（新增）
Favorate.toggleFavorite = async function(userId, videoId) {
  try {
    // 检查是否已经收藏
    const existingFavorite = await this.findOne({
      where: {
        user_id: userId,
        video_id: videoId
      }
    });
    
    if (existingFavorite) {
      // 已收藏，取消收藏
      await existingFavorite.destroy();
      // 获取更新后的收藏数
      const favoriteCount = await this.count({ where: { video_id: videoId } });
      return { favorited: false, favoriteCount };
    } else {
      // 未收藏，创建收藏
      await this.create({
        user_id: userId,
        video_id: videoId
      });
      // 获取更新后的收藏数
      const favoriteCount = await this.count({ where: { video_id: videoId } });
      return { favorited: true, favoriteCount };
    }
  } catch (error) {
    console.error('切换收藏状态失败详情:', error);
    throw new Error('切换收藏状态失败: ' + error.message);
  }
};

// 类方法：检查是否已收藏（新增）
Favorate.isFavorited = async function(userId, videoId) {
  const favorite = await this.findOne({
    where: {
      user_id: userId,
      video_id: videoId
    }
  });
  return favorite !== null;
};

// 类方法：批量检查收藏状态（新增）
Favorate.batchCheckFavorited = async function(userId, videoIds) {
  const favorites = await this.findAll({
    where: {
      user_id: userId,
      video_id: videoIds
    },
    attributes: ['video_id']
  });
  
  const favoritedIds = favorites.map(fav => fav.video_id);
  return videoIds.map(videoId => ({
    videoId,
    favorited: favoritedIds.includes(videoId)
  }));
};

// 类方法：批量创建收藏（新增）
Favorate.batchCreateFavorites = async function(userId, videoIds) {
  try {
    // 检查哪些视频已经被收藏
    const existingFavorites = await this.findAll({
      where: {
        user_id: userId,
        video_id: videoIds
      },
      attributes: ['video_id']
    });
    
    const existingVideoIds = existingFavorites.map(fav => fav.video_id);
    const newVideoIds = videoIds.filter(id => !existingVideoIds.includes(id));
    
    if (newVideoIds.length === 0) {
      return 0;
    }
    
    // 批量创建收藏
    const favoriteData = newVideoIds.map(videoId => ({
      user_id: userId,
      video_id: videoId
    }));
    
    const result = await this.bulkCreate(favoriteData);
    return result.length;
  } catch (error) {
    throw new Error('批量创建收藏失败');
  }
};

// 类方法：批量删除收藏（新增）
Favorate.batchDeleteFavorites = async function(userId, videoIds) {
  const result = await this.destroy({
    where: {
      user_id: userId,
      video_id: videoIds
    }
  });
  return result;
};

module.exports = Favorate;

// 导出到全局，方便其他模块使用
global.Favorate = Favorate;